package com.dc.web.controller;


import com.dc.constant.MessageConstant;
import com.dc.dao.CalibrationWaterCleanChildDao;
import com.dc.dao.CalibrationWaterCleanDao;
import com.dc.dao.ShipDao;
import com.dc.entity.*;
import com.dc.exception.ServiceException;
import com.dc.model.AjaxResult;
import com.dc.model.PageListBody;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

@Api(tags = "6-涂装清洁超水除锈-1-超水清洁")
@RestController
@RequestMapping("/api/calibration_water_clean")
@Slf4j
public class CalibrationWaterCleanController {

    @Resource
    CalibrationWaterCleanDao calibrationWaterCleanDao;

    @Resource
    CalibrationWaterCleanChildDao calibrationWaterCleanChildDao;

    @Resource
    ShipDao shipDao;

    @GetMapping("/list")
    public AjaxResult list(PageListBody body) {

        Integer pageNumber = body.getPageNumber();
        pageNumber = ObjectUtils.defaultIfNull(pageNumber, 1);
        Integer pageSize = body.getPageSize();
        pageSize = ObjectUtils.defaultIfNull(pageSize, 20);

        PageRequest pageRequest = PageRequest.of(pageNumber - 1, pageSize);

        Page<CalibrationWaterCleanEntity> all = calibrationWaterCleanDao.findAll(pageRequest);

        all.getContent().forEach(t-> {
            t.setShipId(t.getShip().getId());
            t.setShipName(t.getShip().getName());
        });

        return AjaxResult.success(all);
    }

    @GetMapping("/{id}")
    public AjaxResult show(@PathVariable("id") Long id) {
        Optional<CalibrationWaterCleanEntity> optional = calibrationWaterCleanDao.findById(id);
        if(!optional.isPresent()) {
            throw new ServiceException(MessageConstant.ERR_CALIBRATION_MISSION);
        }
        CalibrationWaterCleanEntity entity = optional.get();
        entity.setShipId(entity.getShip().getId());
        entity.setShipName(entity.getShip().getName());
        return AjaxResult.success(entity);
    }

    @PostMapping()
    public AjaxResult add(@RequestBody CalibrationWaterCleanEntity entity) {
        entity.setId(null);
        Optional<ShipEntity> optionalShip = shipDao.findById(entity.getShipId());
        if(!optionalShip.isPresent()) {
            throw new ServiceException(MessageConstant.ERR_SHIP_MISSING);
        }
        ShipEntity ship = optionalShip.get();
        entity.setShip(ship);
        // 动态计算
        calc(entity);

        CalibrationWaterCleanEntity save = calibrationWaterCleanDao.save(entity);
        save.setShipName(ship.getName());
        return AjaxResult.success(save);
    }

    @PutMapping("/{id}")
    public AjaxResult update(@PathVariable("id") Long id, @RequestBody CalibrationWaterCleanEntity entity) {
        Optional<CalibrationWaterCleanEntity> optionalWaterClean = calibrationWaterCleanDao.findById(id);
        if(!optionalWaterClean.isPresent()) {
            throw new ServiceException(MessageConstant.ERR_CALIBRATION_MISSION);
        }

        CalibrationWaterCleanEntity waterCleanEntity = optionalWaterClean.get();

        if(!waterCleanEntity.getShip().getId().equals(entity.getShipId())) {      // 如果ship有更换，则更新shipId，否则不更新shipID
            Optional<ShipEntity> optionalShip = shipDao.findById(entity.getShipId());
            if(!optionalShip.isPresent()) {
                throw new ServiceException(MessageConstant.ERR_SHIP_MISSING);
            }
            ShipEntity ship = optionalShip.get();
            waterCleanEntity.setShip(ship);
        }

        //////////// 更新字段
        waterCleanEntity.setArea(entity.getArea());
        ///////////

        /////////// 动态更新
        calc(waterCleanEntity);
        //////////

        ShipEntity ship = waterCleanEntity.getShip();

        CalibrationWaterCleanEntity save = calibrationWaterCleanDao.save(waterCleanEntity);
        save.setShipId(ship.getId());
        save.setShipName(ship.getName());
        save.getInner().forEach(t -> t.setPid(save.getId()));

        return AjaxResult.success(save);
    }

    @DeleteMapping("/{id}")
    public AjaxResult delete(@PathVariable("id") Long id) {
        Optional<CalibrationWaterCleanEntity> optional = calibrationWaterCleanDao.findById(id);
        if (optional.isPresent()) {
            CalibrationWaterCleanEntity entity = optional.get();
            List<CalibrationWaterCleanChildEntity> inner = entity.getInner();

            if(ObjectUtils.isNotEmpty(inner)) {
                Collection<Long> collect = inner.stream().map(CalibrationWaterCleanChildEntity::getId).collect(Collectors.toList());
                calibrationWaterCleanChildDao.deleteAllById(collect);
            }
            calibrationWaterCleanDao.deleteById(id);

        }
        return AjaxResult.success();
    }

    /////////////////////////////////////// child ////////////////////////////////////////////

    @GetMapping("/child/{id}")
    public AjaxResult showChild(@PathVariable("id") Long id) {
        Optional<CalibrationWaterCleanChildEntity> optional = calibrationWaterCleanChildDao.findById(id);
        CalibrationWaterCleanChildEntity entity = null;
        if (optional.isPresent()) {
            entity = optional.get();
            entity.setPid(entity.getCalibrationWaterCleanEntity().getId());
            return AjaxResult.success(entity);
        } else {
            return AjaxResult.error("数据不存在! id = " + id);
        }
    }

    @PostMapping("/child")
    public AjaxResult addChild(@RequestBody CalibrationWaterCleanChildEntity entity) {
        entity.setId(null);
        Optional<CalibrationWaterCleanEntity> optional = calibrationWaterCleanDao.findById(entity.getPid());
        if(!optional.isPresent()) {
            throw new ServiceException(MessageConstant.ERR_CALIBRATION_MISSION);
        }
        CalibrationWaterCleanEntity calibrationWaterCleanEntity = optional.get();
        entity.setCalibrationWaterCleanEntity(calibrationWaterCleanEntity);
        CalibrationWaterCleanChildEntity save = calibrationWaterCleanChildDao.save(entity);
        ////////////////////////////////
        // 动态计算
        calibrationWaterCleanEntity.getInner().add(entity);

        calc(calibrationWaterCleanEntity);

        // 查询父，进行计算
        calibrationWaterCleanDao.save(calibrationWaterCleanEntity);

        return AjaxResult.success(save);
    }

    @PutMapping("/child/{id}")
    public AjaxResult updateChild(@PathVariable("id") Long id, @RequestBody CalibrationWaterCleanChildEntity entity) {
        entity.setId(id);
        Optional<CalibrationWaterCleanEntity> optional = calibrationWaterCleanDao.findById(entity.getPid());
        if(!optional.isPresent()) {
            throw new ServiceException(MessageConstant.ERR_CALIBRATION_MISSION);
        }
        CalibrationWaterCleanEntity calibrationWaterCleanEntity = optional.get();
        entity.setCalibrationWaterCleanEntity(calibrationWaterCleanEntity);
        CalibrationWaterCleanChildEntity save = calibrationWaterCleanChildDao.save(entity);
        ///////////////////////////////////////
        // 动态计算
        calc(calibrationWaterCleanEntity);

        // 查询父，进行计算
        calibrationWaterCleanDao.save(calibrationWaterCleanEntity);

        save.setPid(entity.getPid());
        return AjaxResult.success(save);
    }

    @DeleteMapping("/child/{id}")
    public AjaxResult deleteChild(@PathVariable("id") Long id) {
        Optional<CalibrationWaterCleanChildEntity> childEntityOptional = calibrationWaterCleanChildDao.findById(id);
        if(childEntityOptional.isPresent()) {
            CalibrationWaterCleanChildEntity childEntity = childEntityOptional.get();
            CalibrationWaterCleanEntity calibrationWaterCleanEntity = childEntity.getCalibrationWaterCleanEntity();
            calibrationWaterCleanEntity.getInner().remove(childEntity);
            // 动态计算
            calc(calibrationWaterCleanEntity);

            calibrationWaterCleanDao.save(calibrationWaterCleanEntity);

            calibrationWaterCleanChildDao.deleteById(id);
            return AjaxResult.success();
        } else {
            return AjaxResult.error("数据不存在！! id = " + id);
        }
    }

    private CalibrationWaterCleanEntity calc(CalibrationWaterCleanEntity entity) {

        // power
        try {
            List<CalibrationWaterCleanChildEntity> inner = entity.getInner();
            double power = inner.stream()
                    .mapToDouble(CalibrationWaterCleanChildEntity::getPowerByHour)
                    .reduce(Double::sum)
                    .orElse(0.);
            entity.power = power;
        } catch (Exception e) {
            entity.power = 0.;
        }


        // powerByUnit
        try {
            entity.powerUnit = entity.power / entity.area;
        } catch (Exception e) {
            entity.powerUnit = 0.;
        }

        return entity;
    }

}
